﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using AffordoPlugin.Enum;
using AffordoPlugin.Helper;
using AffordoPlugin.Model;
using Spire.Pdf;
using Spire.Pdf.Graphics;
using Spire.Pdf.HtmlConverter;
using Spire.Pdf.Print;

namespace AffordoPlugin.Print
{
	public class PrintUtil
	{
		public const float CM_1 = 28.3F; //1cm = 28.3像素
		public const float INCH_1 = 2.54F; //1英寸=2.54cm

		public List<string> GetPrintDevice()
		{
			var printDevices = new List<string>();

			foreach (var printer in PrinterSettings.InstalledPrinters)
			{
				printDevices.Add(printer.ToString());
			}

			return printDevices;
		}

		public bool Print(Message<PrintContent> message)
		{
			try
			{
				var printer = ConfigurationHelper.GetAppSettingValue("Printer");
				message.content.device = string.IsNullOrEmpty(message.content.device) ? printer : message.content.device;

				var success = true;
				switch (message.content.dataType)
				{
					case DataTypeEnum.File:
						{
							success = PrintFile(message);
						}
						break;
					case DataTypeEnum.Html:
						{
							success = PrintHtml(message);
						}
						break;
					case DataTypeEnum.Url:
						{
							success = PrintUrl(message);
						}
						break;
				}

				return success;
			}
			catch (Exception ex)
			{
				LogHelper.Error("Print异常" + ex.Message + ex.InnerException?.Message ?? "");

				return false;
			}
		}

		private bool PrintFile(Message<PrintContent> message)
		{
			var pdf = new PdfDocument();
			try
			{
				if (message.content.fileType == FileTypeEnum.IMG)
				{
					var pdfImage = PdfImage.FromFile(message.content.body);

					pdf.PageSettings.Width = message.content.width == 0 ? pdfImage.Width : message.content.width * CM_1;
					pdf.PageSettings.Height = message.content.height == 0 ? pdfImage.Height : message.content.height * CM_1;

					var width = pdf.PageSettings.Width;
					var height = pdf.PageSettings.Height;

					var page = pdf.Pages.Add();



					page.Canvas.DrawImage(pdfImage, new PointF() { X = 0, Y = 0 }, new Size { Width = (int)(width * 0.9f), Height = (int)(height * 0.9f) });
				}
				else if (message.content.fileType == FileTypeEnum.IMGBASE64)
				{
					var index = message.content.body.IndexOf("base64,");
					var base64 = message.content.body.Substring(index + 7);
					var ms = new MemoryStream(Convert.FromBase64String(base64));

					//var paper = new PaperSize("Custom", 196, 118);

					//var pd = new PrintDocument();
					//pd.PrinterSettings.PrinterName = message.content.device;
					//pd.PrinterSettings.Copies = message.content.printQty;
					//pd.PrintController = new StandardPrintController();
					//pd.DefaultPageSettings.PaperSize = paper;

					//pd.PrintPage += (sender, e) =>
					//{

					//	int widthDPI = (int)e.Graphics.DpiX;
					//	int heightDPI = (int)e.Graphics.DpiY;

					//	Image i = Image.FromStream(ms);


					//	//int height = i.Height * heightDPI / 162;// Convert.ToInt32(i.Height / CM_1 / INCH_1)*heightDPI; //98 * heightDPI / 100; //i.Height *heightDPI/162 ;
					//	//int width = i.Width * widthDPI / 162;// Convert.ToInt32(i.Width / CM_1 / INCH_1) * widthDPI; //255 * widthDPI / 100; //i.Width * widthDPI/162 ;

					//	e.Graphics.DrawImage(i, 0, 0, i.Width, i.Height);


					//	//e.Graphics.DrawImage(i, 0, 0, new Rectangle(0, 0, i.Width, i.Height), GraphicsUnit.Pixel);
					//	//e.Graphics.DrawImageUnscaled(i, 0, 0);

					//};

					//pd.Print();

					//return true;


					var pdfStream =  ImgToPDF.ImgToPDFStream(ms);
					
					pdf.LoadFromStream(pdfStream);
					//	var pdfImage = PdfImage.FromStream(ms);



					//	pdf.PageSettings.Width =  message.content.width == 0 ? pdfImage.Width : message.content.width * CM_1;
					//	pdf.PageSettings.Height =  message.content.height == 0 ? pdfImage.Height : message.content.height * CM_1;

					//	var width = 600; //pdf.PageSettings.Width;
					//	var height = 600; //pdf.PageSettings.Height;

					//	var page = pdf.Pages.Add();

					//	page.Canvas.DrawImage(pdfImage, new RectangleF(0,0,300,150));
				}
				else
				{
					pdf.LoadFromFile(message.content.body);
				}

				//pdf.SaveToFile("E://aa.pdf");

				if (message.content.paperHeight > 0 && message.content.paperWidth > 0)
				{
					//PaperSize paper = new PaperSize("Custom", 300, 10);
					PaperSize paper = new PaperSize("Custom", (int)(message.content.paperWidth / INCH_1 * 100), (int)(message.content.paperHeight / INCH_1 * 100));
					paper.RawKind = (int)PaperKind.Custom;
					pdf.PrintSettings.PaperSize = paper;
				}


				pdf.SaveToFile("E://aaaa.pdf");

				pdf.PrintSettings.PrinterName = message.content.device;
				pdf.PrintSettings.Copies = message.content.printQty;
				pdf.PrintSettings.PrintController = new StandardPrintController();
				pdf.PrintSettings.PrinterResolutionKind = PdfPrinterResolutionKind.High;
				pdf.PrintSettings.SelectSinglePageLayout(PdfSinglePageScalingMode.FitSize, false);


				pdf.Print();

				return true;
			}
			catch (Exception ex)
			{
				LogHelper.Error("PrintFile异常" + ex.Message + ex.InnerException?.Message ?? "");

				return false;
			}
			finally
			{
				pdf?.Close();
				pdf?.Dispose();
			}
		}



		private bool PrintHtml(Message<PrintContent> message)
		{
			var pdf = new PdfDocument();
			try
			{
				//加载几页
				var pdfPageSetting = new PdfPageSettings();

				if (message.content.width > 0)
				{
					pdfPageSetting.Width = message.content.width * CM_1;
				}

				if (message.content.height > 0)
				{
					pdfPageSetting.Height = message.content.height * CM_1;
				}

				var pdfFormat = new PdfHtmlLayoutFormat
				{
				};

				var thread = new Thread(() =>
				{
					pdf.LoadFromHTML(message.content.body, false, pdfPageSetting, pdfFormat);

				});
				// set to single thread
				thread.SetApartmentState(ApartmentState.STA);
				thread.Start();
				thread.Join();

				if (message.content.paperHeight > 0 && message.content.paperWidth > 0)
				{
					PaperSize paper = new PaperSize("Custom", (int)(message.content.paperWidth / INCH_1 * 100), (int)(message.content.paperHeight * 100));
					paper.RawKind = (int)PaperKind.Custom;
					pdf.PrintSettings.PaperSize = paper;
				}

			//	pdf.SaveToFile("E://aa.pdf");

				pdf.PrintSettings.PrinterName = message.content.device;
				pdf.PrintSettings.Copies = message.content.printQty;
				pdf.PrintSettings.PrintController = new StandardPrintController();
				pdf.PrintSettings.SelectSinglePageLayout(PdfSinglePageScalingMode.FitSize, false);

				pdf.Print();

				return true;
			}
			catch (Exception ex)
			{
				LogHelper.Error("PrintFile异常" + ex.Message + ex.InnerException?.Message ?? "");

				return false;
			}
			finally
			{
				pdf?.Close();
				pdf?.Dispose();
			}
		}

		private bool PrintUrl(Message<PrintContent> message)
		{
			var pdf = new PdfDocument();
			try
			{
				//非文件，图片的
				if (message.content.fileType == FileTypeEnum.NONE)
				{
					var pdfPageSetting = new PdfPageSettings();

					if (message.content.width > 0)
					{
						pdfPageSetting.Width = message.content.width*CM_1;
					}

					if (message.content.height > 0)
					{
						pdfPageSetting.Height = message.content.height*CM_1;
					}

					var pdfFormat = new PdfHtmlLayoutFormat();

					var thread = new Thread(() =>
					{
						pdf.LoadFromHTML(message.content.body, false, pdfPageSetting, pdfFormat);

					});

					// set to single thread
					thread.SetApartmentState(ApartmentState.STA);
					thread.Start();
					thread.Join();

				}
				else if (message.content.fileType == FileTypeEnum.IMG)
				{
					var stream = HttpHelper.GetHttpStream(message.content.body);

					var pdfImage = PdfImage.FromStream(stream);

					pdf.PageSettings.Width = message.content.width == 0 ? pdfImage.Width : message.content.width*CM_1;
					pdf.PageSettings.Height = message.content.height == 0 ? pdfImage.Height : message.content.height*CM_1;

					var width = pdf.PageSettings.Width;
					var height = pdf.PageSettings.Height;

					var page = pdf.Pages.Add();

					page.Canvas.DrawImage(pdfImage, new PointF() { X = 0, Y = 0 },new SizeF { Width = width*2/3,Height=height*2/3});
				}
				else
				{
					var stream = HttpHelper.GetHttpStream(message.content.body);

					pdf.LoadFromStream(stream);
				}

				//pdf.SaveToFile("D://bb.pdf");

				if (message.content.paperHeight > 0 && message.content.paperWidth > 0)
				{
					PaperSize paper = new PaperSize("Custom", (int)(message.content.paperWidth / INCH_1 * 100), (int)(message.content.paperHeight * 100));
					paper.RawKind = (int)PaperKind.Custom;
					pdf.PrintSettings.PaperSize = paper;
				}

				pdf.PrintSettings.PrinterName = message.content.device;
				pdf.PrintSettings.Copies = message.content.printQty;
				pdf.PrintSettings.PrintController = new StandardPrintController();
				pdf.PrintSettings.SelectSinglePageLayout(PdfSinglePageScalingMode.FitSize, false);

				pdf.Print();

				return true;
			}
			catch (Exception ex)
			{
				LogHelper.Error("PrintFile异常" + ex.Message + ex.InnerException?.Message ?? "");

				return false;
			}
			finally
			{
				pdf?.Close();
				pdf?.Dispose();
			}
		}
	}
}
